﻿using System;
using T.FAS.Runtime.Base.Entity;

namespace T.FAS.Runtime.DataAccess.SQLDom
{
    /// <summary>
    /// 动态条件SQL语句类
    /// </summary>
    /// <remarks>动态条件</remarks>
    [Serializable]
    public class ConditionStatement : SqlElement
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public ConditionStatement()
            : base()
        {
            base.CreateChildCollection();
        }

        #region 常量

        /// <summary> 
        /// ConditionStatement 
        /// </summary>
        public const string CONDITIONSTATEMENT = "ConditionStatement";

        /// <summary> 
        /// ConditionString 
        /// </summary>
        public const string CONDITIONSTRING = "ConditionString";

        #endregion

        #region 属性

        //包裹列名的方法
        public Func<string, string> FieldNameWraps { get; set; }

        private OperatorType logicalOperator = OperatorType.And;

        /// <summary>
        /// 关系运算符
        /// </summary>
        public OperatorType LogicalOperator
        {
            get
            {
                return logicalOperator;
            }
            set
            {
                logicalOperator = value;
            }
        }

        /// <summary>
        /// 动态条件SQL字符串
        /// </summary>
        public string ConditionString { get; set; }

        public bool IsExpression { get; set; }

        public ConditionField ConditionField { get; set; } = new ConditionField();

        public ConditionFieldValue ConditionFieldValue { get; set; } = new ConditionFieldValue();

        public RelationalOperator RelationalOperator { get; set; }

        public DatabaseType DbType { get; set; }


        #endregion

        #region 方法

        public void SetLogicalOperator(OperatorType loperator)
        {
            LogicalOperator = loperator;
        }

        /// <summary>
        /// 转换成SQL语句
        /// </summary>
        /// <returns>SQL语句</returns>
        public override string ToSQL()
        {
            if (string.IsNullOrEmpty(ConditionString) == false)
                return ConditionString;

            var relationOper = RelationalOperatorUtis.ConvertToString(RelationalOperator, DbType);

            string tableName = ConditionField.Table.TableName;
            string tablePrefix = ConditionField.Table.TablePrefix;
            string fieldName = ConditionField.FieldName;
            string conditionFieldName = ConditionFieldValue.ConditionFieldName;

            tableName = GetWrapString(tableName);
            tablePrefix = GetWrapString(tablePrefix);
            fieldName = GetWrapString(fieldName);
            conditionFieldName = GetWrapString(conditionFieldName);

            //paramName是生成变量替换的参数名称，例如 @DO_TestDBEscapeCharV2_LastModifyTime，不能增加系统转义符
            string paramName = ConditionField.Table.TablePrefix + "_" + ConditionFieldValue.ConditionFieldName;
            if (ConditionFieldValue.IsNull)
            {
                return string.Format("{0}.{1} is null ", tableName, fieldName);
            }
            else
            {
                if (relationOper.Value)
                {
                    //统一数据访问服务修改v1.1 sql变量占位符加入表名前缀:表名_列名
                    return string.Format("{0}.{1} {2} @{3}",
                        //ConditionField.Table.TableName,
                        tablePrefix,
                        fieldName,
                        relationOper.Key,
                        //ConditionFieldValue.ConditionFieldName
                        paramName
                        );
                }
                else
                {
                    return string.Format(
                        tableName + "." + fieldName + " " + relationOper.Key,
                        //ConditionFieldValue.ConditionFieldName
                        paramName
                        );
                }
            }           
        }

        private string GetWrapString(string str)
        {
            if (this.FieldNameWraps == null)
                return str;
            return this.FieldNameWraps(str);
        }
        #endregion
    }
}
